#include "Hero.h"
#include <iostream>
using namespace std;

Hero* creerHero(int x,int y,int niv,int vie,arme* a)
{
    Hero* h;
    h=new(Hero);	///@brief on alloue la place pour le hero
    initHero(h,x,y,niv,a,vie);	///@brief puis on crée le hero avec un nom de variable, une position en x et en y, le niveau du hero (qui sera utile quand on gerera des levels), l'arme utilisée par le hero et un nombre de vie
    return h;
}

void initHero(Hero* h,int x,int y,int niv,arme* a,int vie)
{
    h->a=a; /// on lui met une arme
    h->niveau=niv;	/// on lui donne un niveau
    h->pv=100;	/// puis un nombre points de vie,
    h->vie=vie;	/// un nombre de vie,
    h->x=x;	/// une position en x,
    h->y=y;	/// et une position en y
    h->terrain=1;	/// on lui assigne aussi un terrain parce que sinon le hero n'est pas sur le terrain
    h->avancement=0;/// on initialise l'avancement du héros à 0 car il est dans le jeu
    h->direction='b';/// comme le point de départ est à gauche sur le terrain on le tourne vers la droite
    h->score=0;///il part avec un score de 0 point
}

void supprimeHero(Hero* h)
{
    delete(h);
}

int heroGetX(const Hero* h)
{
    return h->x;
}

int heroGetY(const Hero* h)
{
    return h->y;
}

int heroGetvie(const Hero* h)
{
    return h->vie;
}

int heroGetpv(const Hero* h)
{
    return h->pv;
}

arme* heroGetarme(const Hero* h)
{
    return h->a;
}

int heroGetniveau(const Hero* h)
{
    return h->niveau;
}

int heroGetterrain(const Hero* h)
{
    return h->terrain;
}

void heroSetX(Hero* h,int x)
{
    h->x=x;
}

void heroSetY(Hero* h,int y)
{
    h->y=y;
}

void heroSetvie(Hero* h,int vie)
{
    h->vie=vie;
}

void heroSetpv(Hero* h,int pv)
{
    h->pv=pv;
}

void heroSetarme(Hero* h,arme* a)
{
    h->a=a;
}

void heroSetniveau(Hero* h,int niv)
{
    h->niveau=niv;
}

void heroSetterrain(Hero* h,int ter)
{
    h->terrain=ter;
}

void heroGauche(Hero* h, Niveau* niv)
{
	Terrain* t;
    t=nivChercheTerrain(niv,heroGetniveau(h),heroGetterrain(h));///On récupère le numéro du terrain sur lequel il se trouve
    if ((terPosHeroOk(t,h->x-1,h->y)!=0) && (terPosHeroOk(t,h->x-1,h->y+1)<8)/**On teste si il n'y a pas de mur à gauche*/ && (terPosHeroOk(t,h->x-1,h->y+1)!=1))/**et si le sol s'arrete à gauche*/
    {/// Si les deux tests rendent 1
        (h->x)--;///on le déplace à gauche de 1
    }
    heroSetDirection(h,'g');
}

void heroDroite(Hero* h, Niveau* niv)
{
	Terrain* t;
    t=nivChercheTerrain(niv,heroGetniveau(h),heroGetterrain(h));///On récupère le numéro du terrain sur lequel il se trouve
    if ((terPosHeroOk(t,h->x+1,h->y)!=0) && (terPosHeroOk(t,h->x+1,h->y+1)<8)/**On teste si il n'y a pas de mur à droite*/ && (terPosHeroOk(t,h->x+1,h->y+1)!=1))/**et si le sol s'arrete à droite*/
    {/// Si les deux tests rendent 1
        (h->x)++;///on le déplace à gauche de 1
    }
    heroSetDirection(h,'d');
}

void heroHaut(Hero* h, Niveau* niv)
{
    Terrain* t;
    t=nivChercheTerrain(niv,heroGetniveau(h),heroGetterrain(h));///On récupère le numéro du terrain sur lequel il se trouve
    if ((terPosHeroOk(t,h->x,h->y)==2)/**on teste s'il y a une echelle sur laquelle il peut monter*/ && (terPosHeroOk(t,h->x,h->y-1)!=0)/** et si il peut y monter*/ )
	{
		(h->y)--;///Si oui on le fait monter sur l'échelle
	}
	heroSetDirection(h,'h');
}

void heroBas(Hero* h, Niveau* niv)
{
    Terrain* t;
    t=nivChercheTerrain(niv,heroGetniveau(h),heroGetterrain(h));///On récupère le numéro du terrain sur lequel il se trouve
    if (terPosHeroOk(t,h->x,h->y+1)==2)///teste si il y a une echelle en dessous
	{
		(h->y)++;///Si oui on le fait descendre
	}
	heroSetDirection(h,'b');
}

void heroSort(Hero* h, Niveau* niv)
{
    Terrain* t;
    int* i;
    int* j;
    i=new(int);
    j=new(int);
    t=nivChercheTerrain(niv,heroGetniveau(h),heroGetterrain(h));///On récupère le numéro du terrain sur lequel il se trouve
    if(terPosHeroOk(t,h->x,h->y)==4)
    {///si il y a une porte de sortie de niveau
        if(nivGetSuivant(niv)!=NULL)///et qu'il y a un niveau suivant
                    {
                        (h->terrain)=1;/// on le met sur le 1er terrain
                        (h->niveau)=(h->niveau)+1;/// du niveau suivant
                        t=nivChercheTerrain(niv,heroGetniveau(h),heroGetterrain(h));///On récupère le numéro du terrain sur lequel il se trouve
						RechercheDebutTerrain(t,i,j);///On cherche le debut de terrain
						(h->x)=*i;///et on y place le héros
						(h->y)=*j;
						h->score=h->score+25;
                    }
         else
         {
			 heroSetAvancement(h,1);
		 }
    }
    else if(terPosHeroOk(t,h->x,h->y)==3)///si le héros est au point de depart du niveau
    {
		{
			if(nivGetPrecedant(niv)!=NULL)///et si il y a un niveau précedent
                    {
                        (h->terrain)=1;///On le ramène au 1er terrain
                        (h->niveau)=(h->niveau)-1;/// du niveau précedent
                        t=nivChercheTerrain(nivGetPrecedant(niv),heroGetniveau(h),heroGetterrain(h));///On récupère le numéro du terrain sur lequel il se trouve
						RechercheDebutTerrain(t,i,j);///On cherche le debut du terrain
						(h->x)=*i;/// et on y place le héros
						(h->y)=*j;
                    }
		}
	}
    delete(i);
    delete(j);
}

int heroGetAvancement(Hero* hero)
{
	return hero->avancement;
}

void heroSetAvancement(Hero* hero,int avancement)
{
	hero->avancement=avancement;
}

char heroGetDirection(Hero* hero)
{
	return hero->direction;
}

void heroSetDirection(Hero* hero, char dir)
{
	hero->direction=dir;
}

int heroGetScore(Hero* hero)
{
	return hero->score;
}

void heroSetScore(Hero* hero, int score)
{
	hero->score=score;
}
